package ccm;

import ccm.common.*;
import ccm.communicate.common.Communicate;
import ccm.communicate.common.NotStartException;
import ccm.communicate.common.SendFailedException;
import ccm.communicate.file.FileSaver;
import ccm.communicate.serial.Serial;
import ccm.communicate.smctp.Smctp;
import ccm.component.AboutJDialog;
import ccm.component.input.InputJPanel;
import ccm.component.input.MultipleInputJPanel;
import ccm.component.oscilloscope.JustFloatDataManager;
import ccm.component.oscilloscope.OscilloscopeDataManager;
import ccm.component.oscilloscope.OscilloscopeJPanel;
import ccm.component.output.OutputJPanel;
import ccm.component.override.JFrame;
import ccm.component.override.VFlowLayout;
import ccm.tools.GenerateImage;
import ccm.tools.Label.Label;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CCMonitor extends JFrame implements ActionListener, ReceiveDataListener, StatusChangeListener
{
    protected       boolean                 inited      =false;
    protected       String                  fileSaverDir=null;
    protected       FileSaver               fileSaver;
    protected       Communicate             communicate;
    protected       Smctp                   smctp;
    protected final JButton                 startJButton;
    protected final JButton                 loadJButton;
    protected final JButton                 cleanJButton;
    protected final OscilloscopeDataManager visualScopeDataManager;
    protected final OutputJPanel            outputJPanel;
    protected       InputJPanel             inputJPanel;
    protected final OscilloscopeJPanel      oscilloscopeJPanel;
    protected final AboutJDialog            aboutJDialog;


    protected final JMenuItem setFileSaverDirJMenuItem;
    protected final JLabel    fileSaverInfoJLabel;

    public CCMonitor() throws TooManyListenerException
    {
        super();
        readConfig();
        setSize(1400,900);
        setLayout(new BorderLayout());

        {
            JMenuBar jMenuBar=new JMenuBar();
            setJMenuBar(jMenuBar);
            {
                JMenu jMenu=new JMenu("设置");
                jMenuBar.add(jMenu);
                setFileSaverDirJMenuItem=new JMenuItem("设置数据记录路径");
                jMenu.add(setFileSaverDirJMenuItem);
                setFileSaverDirJMenuItem.addActionListener(this);
            }
            {
                JMenu jMenu=new JMenu("帮助");
                jMenuBar.add(jMenu);
                JMenuItem aboutJMenuItem=new JMenuItem("关于");
                jMenu.add(aboutJMenuItem);
                aboutJMenuItem.addActionListener(new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        aboutJDialog.setVisible(true);
                    }
                });
            }
        }


        // JSplitPane jSplitPane1=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        // add(jSplitPane1,BorderLayout.CENTER);
        // jSplitPane1.setOneTouchExpandable(true);
        // jSplitPane1.setDividerLocation(0);
        // jSplitPane1.add(imageJPanel=new ManualResizeableImageJPanel());
        // imageDecoder=new ImageDecoder();
        // imageDecoder.addReceiveImageListener(imageJPanel);


        JSplitPane jSplitPane2=new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        // jSplitPane1.add(jSplitPane2);
        add(jSplitPane2,BorderLayout.CENTER);
        jSplitPane2.setOneTouchExpandable(true);
        jSplitPane2.setDividerLocation(550);
        jSplitPane2.add(oscilloscopeJPanel=new OscilloscopeJPanel(visualScopeDataManager=new JustFloatDataManager()));
        jSplitPane2.add(outputJPanel=new OutputJPanel());

        if(inputJPanel==null)
            inputJPanel=new MultipleInputJPanel();
        add(inputJPanel,BorderLayout.SOUTH);
        try
        {
            inputJPanel.addDataReceiveListener(this);
            inputJPanel.addStatusChangeListener(this);
        }catch(TooManyListenerException e)
        {
            e.printStackTrace();
        }

        JPanel leftJPanel=new JPanel();
        add(leftJPanel,BorderLayout.EAST);
        leftJPanel.setLayout(new VFlowLayout());

        if(true||communicate==null||smctp==null)
        {
            communicate=new Serial();
            //communicate=new TcpServer();
            smctp=new Smctp(communicate,0);
        }

        smctp.addStatusChangeListener(this);
        smctp.addReceiveDataListener(outputJPanel,Smctp.CHANNEL_DEBUG);
        if(visualScopeDataManager instanceof ReceiveDataListener)
            smctp.addReceiveDataListener((ReceiveDataListener)visualScopeDataManager,Smctp.CHANNEL_VISUAL_SCOPE);
        // smctp.addReceiveDataListener(imageDecoder,SMCTP.CHANNEL_IMAGE);
        // communicate.addReceiveDataListener(outputJPanel,SMCTP.CHANNEL_IMAGE);
        leftJPanel.add(communicate.getConfigJPanel());
        leftJPanel.add(smctp.getConfigJPanel());

        JPanel operateJPanel=new JPanel();
        leftJPanel.add(operateJPanel);
        operateJPanel.setLayout(new VFlowLayout());
        operateJPanel.setBorder(new TitledBorder("操作"));

        startJButton=new JButton("开始");
        operateJPanel.add(startJButton);
        startJButton.addActionListener(this);

        loadJButton=new JButton("加载");
        operateJPanel.add(loadJButton);
        loadJButton.addActionListener(this);

        cleanJButton=new JButton("清空");
        operateJPanel.add(cleanJButton);
        cleanJButton.addActionListener(this);

        aboutJDialog=new AboutJDialog(this);

        JPanel infoJPanel=new JPanel();
        leftJPanel.add(infoJPanel);
        infoJPanel.setLayout(new VFlowLayout());
        infoJPanel.setBorder(new TitledBorder("信息"));
        infoJPanel.add(fileSaverInfoJLabel=new JLabel("未录制"));


        inited=true;
    }

    public void readConfig()
    {
        try
        {
            ObjectInputStream objectInputStream=new ObjectInputStream(Files.newInputStream(Paths.get(System.getProperty("user.home")+"/"+getTitleString("")+".config")));
            communicate =(Communicate)objectInputStream.readObject();
            inputJPanel =(InputJPanel)objectInputStream.readObject();
            fileSaverDir=(String)objectInputStream.readObject();
            smctp       =(Smctp)objectInputStream.readObject();
            if(smctp!=null&&communicate!=null)
                smctp.setNext(communicate,0);
            objectInputStream.close();
        }catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws TooManyListenerException
    {
        if(args.length==0||args[0].equals("CCMonitor"))
            new CCMonitor().setVisible(true);
        else if(args[0].equals("Label"))
            new Label();
        else if(args[0].equals("GenerateImage"))
            new GenerateImage();
    }

    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource().equals(startJButton))
        {
            if(smctp.isOpen())
                smctp.stop();
            else
            {
                clear();
                smctp.start();
            }
        }
        else if(e.getSource().equals(cleanJButton))
        {
            clear();
        }
        else if(e.getSource().equals(loadJButton))
        {
            try
            {
                communicate.stop();
                clear();
                JFileChooser jFileChooser=new JFileChooser(fileSaverDir);
                jFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                jFileChooser.showDialog(new JLabel(),"选择");
                smctp.receiveData(new ReceiveDataEvent(this,FileSaver.readAll(jFileChooser.getSelectedFile())));
            }catch(IOException ex)
            {
                ex.printStackTrace();
            }
        }
        else if(e.getSource().equals(setFileSaverDirJMenuItem))
        {
            JFileChooser fileChooser=new JFileChooser(fileSaverDir);
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int returnVal=fileChooser.showOpenDialog(fileChooser);
            if(returnVal==JFileChooser.APPROVE_OPTION)
            {
                fileSaverDir=fileChooser.getSelectedFile().getAbsolutePath();
                System.out.println(fileSaverDir);
                writeConfig();
            }
        }
    }

    protected void clear()
    {
        if(fileSaver!=null)
        {
            communicate.removeReceiveDataListener(fileSaver,0);
            fileSaver.stop();
        }
        outputJPanel.clear();
        visualScopeDataManager.clear();
        oscilloscopeJPanel.enableAutoBiasAndResize(true);
    }

    public void writeConfig()
    {
        if(!inited)
            return;
        System.out.println("writeConfig");
        try
        {
            ObjectOutputStream objectOutputStream=new ObjectOutputStream(Files.newOutputStream(Paths.get(System.getProperty("user.home")+"/"+getTitleString("")+".config")));
            objectOutputStream.writeObject(communicate);
            objectOutputStream.writeObject(inputJPanel);
            objectOutputStream.writeObject(fileSaverDir);
            objectOutputStream.writeObject(smctp);
            objectOutputStream.close();
        }catch(IOException e)
        {
            e.printStackTrace();
        }
    }

    public void receiveData(ReceiveDataEvent e)
    {
        if(e.getSource().equals(inputJPanel))
        {
            try
            {
                smctp.send(e.getData());
            }catch(NotStartException ex)
            {
                JOptionPane.showMessageDialog(this,"未开启串口","错误",JOptionPane.ERROR_MESSAGE);
                ex.printStackTrace();
            }catch(SendFailedException ex)
            {
                ex.printStackTrace();
            }
        }
    }

    public void statusChange(StatusChangeEvent e)
    {
        if(e.getSource().equals(smctp)&&(e.getReason()==StatusChangeEvent.START_STOP||e.getReason()==StatusChangeEvent.RESTART))
        {
            startJButton.setText(smctp.isOpen()?"停止":"开始");
            fileSaverInfoJLabel.setText("未录制");
            if(smctp.isOpen())
                try
                {
                    clear();
                    if(fileSaverDir!=null)
                    {
                        final String name=new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
                        final String dir=fileSaverDir+"/"+name+".receive";
                        fileSaver=new FileSaver(dir);
                        communicate.addReceiveDataListener(fileSaver,0);
                        fileSaverInfoJLabel.setText("录制中"+name);
                    }
                }catch(FileNotFoundException|TooManyListenerException ex)
                {
                    ex.printStackTrace();
                }
        }
        else if(e.getReason()==StatusChangeEvent.CONFIG)
            writeConfig();
    }

}
